﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;
using YJKArchMethodLibrary.Utils;
using YJKCodeBase.WinForm;
using YJKRevitCode.RevitDimensionUtility;
using YJKTextDimension.DimCreator;
using YJKTextDimension.Forms;
using YJKView;

namespace YJKTextDimension.Commands
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class CmdAxisDim : YJKCommandManual
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		protected override Result YJKExcute(ExternalCommandData cmdData, ref string message, ElementSet elements)
		{
			if (SwitchView.SetUsableView((CmdViewType)9, cmdData) != Autodesk.Revit.UI.Result.Succeeded)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			this.m_lstAllAxis = this.GetAllAxis();
			if (this.m_lstAllAxis == null || this.m_lstAllAxis.Count < 2)
			{
				YJKMessageBox.Show("图中没有可标注的轴网。");
				return Autodesk.Revit.UI.Result.Failed;
			}
			Process currentProcess = Process.GetCurrentProcess();
            WindowHandle windowHandle = new WindowHandle(currentProcess.MainWindowHandle);
			DlgAxisDim dlgAxisDim = new DlgAxisDim();
			dlgAxisDim.Show(windowHandle);
			int wMsg = 7;
			CmdAxisDim.SendMessage(windowHandle.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			Transaction transaction = new Transaction(this.m_doc, "AxisDim");
			transaction.Start();
			try
			{
				while (this.AxisDim(dlgAxisDim) != Result.Cancelled)
				{
				}
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
			}
			transaction.Commit();
			dlgAxisDim.Close();
			return base.YJKExcute(cmdData, ref message, elements);
		}

		private Result AxisDim(DlgAxisDim dlg)
		{
			XYZ startPoint = null;
			XYZ endPoint = null;
			Element element = null;
			Element element2 = null;
			if (this.SelectAxis("请点取第一平行轴线的起点", ref element, ref startPoint) != Result.Succeeded)
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
            if (this.SelectAxis("请点取第二平行轴线的起点", ref element2, ref endPoint) != Result.Succeeded)
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			if (element.Id == element2.Id)
			{
				YJKMessageBox.Show("选择的两轴线应该平行并且是同一类型。");
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			Line line = YJKLineEx.YJKGetBound(startPoint, endPoint);
			Line line2 = line.Clone() as Line;
			GridType elem = this.m_doc.GetElement(element.GetTypeId()) as GridType;
			int num = elem.GetParameter(BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).AsInteger();
			if (num != 0)
			{
				elem.GetParameter(BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).Set(0);
				this.m_doc.Regenerate();
			}
			if (!this.IsAxisParallel(element, element2, ref line))
			{
				elem.GetParameter(BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).Set(num);
				this.m_doc.Regenerate();
				YJKMessageBox.Show("选择的两轴线应该平行并且是同一类型。");
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			XYZ hyendPoint = line.GetEndPoint(0);
			line.MakeUnbound();
			XYZ xyz = this.AxisIntersectLine(element, line, hyendPoint);
			XYZ xyz2 = this.AxisIntersectLine(element2, line, hyendPoint);
			if (xyz != null && xyz2 != null)
			{
				line.MakeBound(Math.Min(line.Project(xyz).Parameter, line.Project(xyz2).Parameter), Math.Max(line.Project(xyz).Parameter, line.Project(xyz2).Parameter));
			}
			else
			{
				line = line2;
			}
			line = DimPublicFunc.ExtendLine(line, 2, 0.1);
			List<Element> list = this.LineCrossAxises(line);
			list = this.GetParallelAxis(element, list);
			if (list == null || list.Count < 2)
			{
				elem.GetParameter(BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).Set(num);
				this.m_doc.Regenerate();
				YJKMessageBox.Show("两点之间没有可标注的轴线。");
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			if (!dlg.GetDlgItemData())
			{
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			double num2 = AssistFunc.mmToFeet((double)dlg.DistAxisNumber);
			double num3 = AssistFunc.mmToFeet((double)dlg.DistBetweenDim);
			if (num2 == 0.0)
			{
				YJKMessageBox.Show("标注到轴号的距离必须大于0.");
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			if (num3 == 0.0)
			{
				YJKMessageBox.Show("一二道标注间距必须大于0.");
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			if (dlg.AxisDimType == 0)
			{
				this.DimAxises(list, line, num2, num3, true);
				this.DimAxises(list, line, num2, num3, false);
			}
			else if (dlg.AxisDimType == 1)
			{
				this.DimAxises(list, line, num2, num3, true);
			}
			else
			{
				this.DimAxises(list, line, num2, num3, false);
			}
			elem.GetParameter(BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).Set(num);
			this.m_doc.Regenerate();
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private bool DimAxises(List<Element> lstAxis, Line crossLine, double dDimOffset1, double dDimOffset2, bool bNearCross)
		{
			List<ReferenceInfo> list = new List<ReferenceInfo>();
			this.GetDimRefInfo(lstAxis, crossLine, bNearCross, ref list);
			if (list.Count < 2)
			{
				YJKMessageBox.Show("不能提取轴线的标注参照!");
				return false;
			}
			XYZ axisDimVector = this.GetAxisDimVector(lstAxis[0], crossLine, bNearCross);
			XYZ thePosition = list[0].ThePosition;
			XYZ xyz = thePosition - axisDimVector * 10.0;
			foreach (ReferenceInfo referenceInfo in list)
			{
				XYZ ptExtend = Geometry.CalculateFootPoint(xyz, thePosition, referenceInfo.ThePosition);
				DimPublicFunc.ExtendLine(ptExtend, ref xyz, ref thePosition);
			}
			ReferenceInfo referenceInfo2 = list[0];
			ReferenceInfo referenceInfo3 = list[list.Count - 1];
			xyz = referenceInfo3.ThePosition + axisDimVector * 10.0;
			xyz = Geometry.CalculateFootPoint(referenceInfo3.ThePosition, xyz, thePosition);
			XYZ xyz2 = thePosition - xyz;
			ReferenceInfo axisWallBorderDimRef = this.GetAxisWallBorderDimRef(referenceInfo2.ThePosition, xyz2);
			if (axisWallBorderDimRef != null)
			{
				list.Insert(0, axisWallBorderDimRef);
			}
			ReferenceInfo axisWallBorderDimRef2 = this.GetAxisWallBorderDimRef(referenceInfo3.ThePosition, -xyz2);
			if (axisWallBorderDimRef2 != null)
			{
				list.Add(axisWallBorderDimRef2);
			}
			XYZ ptDim = thePosition - axisDimVector * dDimOffset1;
			ReferenceArray referenceArray = new ReferenceArray();
			referenceArray.Append(list[0].TheReference);
			referenceArray.Append(list[list.Count - 1].TheReference);
			Dimension dimension = DimPublicFunc.CreateLinearDim(this.m_doc, referenceArray, ptDim, axisDimVector, DimensionTypeEnum.AxisDimension);
			if (dimension != null)
			{
				DimPublicFunc.SetDimFlag(dimension, "AxisDim");
			}
			if (list.Count > 2)
			{
				XYZ ptDim2 = thePosition - axisDimVector * (dDimOffset1 + dDimOffset2);
				ReferenceArray referenceArray2 = new ReferenceArray();
				foreach (ReferenceInfo referenceInfo4 in list)
				{
					referenceArray2.Append(referenceInfo4.TheReference);
				}
				Dimension dimension2 = DimPublicFunc.CreateLinearDim(this.m_doc, referenceArray2, ptDim2, axisDimVector, DimensionTypeEnum.AxisDimension);
				if (dimension2 != null)
				{
					DimPublicFunc.SetDimFlag(dimension2, "AxisDim");
				}
			}
			return true;
		}

		private List<Element> GetAllAxis()
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
			List<Grid> list = (from g in filteredElementCollector.OfClass(typeof(Grid))
			select g as Grid).ToList<Grid>();
			FilteredElementCollector filteredElementCollector2 = new FilteredElementCollector(this.m_doc);
			List<MultiSegmentGrid> list2 = (from g in filteredElementCollector2.OfClass(typeof(MultiSegmentGrid))
			select g as MultiSegmentGrid).ToList<MultiSegmentGrid>();
			if (list == null && list2 == null)
			{
				return null;
			}
			foreach (MultiSegmentGrid multiSegmentGrid in list2)
			{
				ICollection<ElementId> gridIds = multiSegmentGrid.GetGridIds();
				for (int i = 0; i < list.Count; i++)
				{
					Grid grid = list[i];
					if (gridIds.Contains(grid.Id))
					{
						list.Remove(grid);
						i--;
					}
				}
			}
			List<Element> list3 = new List<Element>();
			foreach (Grid item in list)
			{
				list3.Add(item);
			}
			foreach (MultiSegmentGrid item2 in list2)
			{
				list3.Add(item2);
			}
			return list3;
		}

		private Result SelectElement(ISelectionFilter filter, string sPrompt, ref Element selElem, ref XYZ ptPick)
		{
			try
			{
				Reference reference = this.m_uiDoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, filter, sPrompt);
				ptPick = reference.GlobalPoint;
				selElem = this.m_doc.GetElement(reference);
			}
			catch
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private Result SelectAxis(string sPrompt, ref Element axisElem, ref XYZ ptPick)
		{
			AxisFilter filter = new AxisFilter();
			while (this.SelectElement(filter, sPrompt, ref axisElem, ref ptPick) == Result.Succeeded)
			{
				GridType elem = this.m_doc.GetElement(axisElem.GetTypeId()) as GridType;
				int num = elem.GetParameter(BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).AsInteger();
				if (num != 0)
				{
					elem.GetParameter(BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).Set(0);
					this.m_doc.Regenerate();
				}
				if (this.IsPointOnAxis(axisElem, ref ptPick))
				{
					if (this.IsAxisCanBeDim(axisElem))
					{
						elem.GetParameter(BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).Set(num);
						this.m_doc.Regenerate();
						return Autodesk.Revit.UI.Result.Succeeded;
					}
					YJKMessageBox.Show("本功能不能标注末端为弧线的轴线。");
				}
				elem.GetParameter(BuiltInParameter.GRID_CENTER_SEGMENT_STYLE).Set(num);
				this.m_doc.Regenerate();
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		private bool IsAxisCanBeDim(Element axis)
		{
			List<Curve> axisCurves = this.GetAxisCurves(axis, true);
			if (axisCurves == null || axisCurves.Count < 1)
			{
				return false;
			}
			Curve curve = axisCurves[0];
			Curve curve2 = axisCurves[axisCurves.Count - 1];
			return !(curve.GetType() != typeof(Line)) && !(curve2.GetType() != typeof(Line));
		}

		private bool IsPointOnAxis(Element axis, ref XYZ ptPick)
		{
			List<Curve> axisCurves = this.GetAxisCurves(axis, false);
			if (axisCurves == null || axisCurves.Count < 1)
			{
				return false;
			}
			foreach (Curve curve in axisCurves)
			{
				if (this.IsPointOnCurve(curve, ref ptPick))
				{
					return true;
				}
			}
			return false;
		}

		private bool IsPointOnCurve(Curve curve, ref XYZ pt)
		{
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			pt = new XYZ(pt.X, pt.Y, hyendPoint.Z);
			if (curve.GetType() == typeof(Line))
			{
				if (Geometry.Is_Point_OnSegment(hyendPoint, hyendPoint2, pt, 1E-09))
				{
					pt = curve.Project(pt).XYZPoint;
					return true;
				}
			}
			else if (curve.GetType() == typeof(Arc))
			{
				Arc arc = curve as Arc;
				if (Geometry.Is_Point_OnSegment(hyendPoint, hyendPoint2, arc.Center, XYZ.BasisZ, pt, 1E-09))
				{
					pt = curve.Project(pt).XYZPoint;
					return true;
				}
			}
			return false;
		}

		private bool IsAxisParallel(Element axis1, Element axis2, ref Line crossLine)
		{
			List<Curve> axisCurves = this.GetAxisCurves(axis1, true);
			List<Curve> axisCurves2 = this.GetAxisCurves(axis2, true);
			if (axisCurves != null)
			{
			}
			List<KeyValuePair<Curve, Curve>> list = new List<KeyValuePair<Curve, Curve>>();
			if (axisCurves.Count != axisCurves2.Count)
			{
				return false;
			}
			for (int i = 0; i < axisCurves.Count; i++)
			{
				for (int j = 0; j < axisCurves2.Count; j++)
				{
					if (this.IsAxisCurveParallel(axisCurves[i], axisCurves2[j]) && axisCurves[i] is Line && axisCurves2[j] is Line)
					{
						list.Add(new KeyValuePair<Curve, Curve>(axisCurves[i], axisCurves2[j]));
					}
				}
			}
			XYZ crossLinePoint = crossLine.GetEndPoint(0);
			list = (from k in list
			orderby crossLinePoint.DistanceTo(this.GetKVPCurveTagPoint(k))
			select k).ToList<KeyValuePair<Curve, Curve>>();
			if (list.Count != 0)
			{
				this.GetNewCrossLine(list[0].Key, ref crossLine);
			}
			return list.Count != 0;
		}

		private XYZ GetKVPCurveTagPoint(KeyValuePair<Curve, Curve> input)
		{
			return (input.Key.Evaluate(0.5, true) + input.Value.Evaluate(0.5, true)) / 2.0;
		}

		private void GetNewCrossLine(Curve curve, ref Line crossCurve)
		{
			if (curve is Line)
			{
				Line line = curve as Line;
				XYZ xyz = new XYZ(-line.Direction.Y, line.Direction.X, line.Direction.Z);
				Line line2 = Line.CreateUnbound(crossCurve.GetEndPoint(0), xyz);
				try
				{
					crossCurve = Line.CreateBound(line2.Project(crossCurve.GetEndPoint(0)).XYZPoint, line2.Project(crossCurve.GetEndPoint(1)).XYZPoint);
					return;
				}
				catch (Exception)
				{
					return;
				}
			}
			if (curve is Arc)
			{
				Arc arc = curve as Arc;
				IntersectionResultArray intersectionResultArray;
				arc.Intersect(crossCurve, out intersectionResultArray);
				XYZ xyz2 = XYZ.Zero;
				if (intersectionResultArray != null)
				{
					xyz2 = intersectionResultArray.get_Item(0).XYZPoint;
				}
				double parameter = arc.Project(xyz2).Parameter;
				Transform transform = arc.ComputeDerivatives(parameter, false);
				XYZ basisX = transform.BasisX;
				Line line3 = Line.CreateUnbound(crossCurve.GetEndPoint(0), basisX);
				try
				{
					crossCurve = Line.CreateBound(line3.Project(crossCurve.GetEndPoint(0)).XYZPoint, line3.Project(crossCurve.GetEndPoint(1)).XYZPoint);
				}
				catch (Exception)
				{
				}
			}
		}

		private bool IsAxisCurveParallel(Curve curve1, Curve curve2)
		{
			if (curve1 is Line && curve2 is Line)
			{
				Line line = curve1 as Line;
				Line line2 = curve2 as Line;
				if (!DimPublicFunc.IsParallel(line.Direction, line2.Direction))
				{
					return false;
				}
			}
			else
			{
				if (!(curve1 is Arc) || !(curve2 is Arc))
				{
					return false;
				}
				Arc arc = curve1 as Arc;
				Arc arc2 = curve2 as Arc;
				if (!Geometry.IsEqual(arc.Center, arc2.Center))
				{
					return false;
				}
			}
			return true;
		}

		private List<Curve> GetAxisCurves(Element axis, bool ifNoReference = true)
		{
			List<Curve> list = new List<Curve>();
			if (axis.GetType() == typeof(Grid))
			{
				list = this.GetGridCurves(axis as Grid);
			}
			else if (axis.GetType() == typeof(MultiSegmentGrid))
			{
				MultiSegmentGrid multiSegmentGrid = axis as MultiSegmentGrid;
				foreach (ElementId elementId in multiSegmentGrid.GetGridIds())
				{
					Element elementById = this.m_doc.GetElementById(elementId);
					List<Curve> gridCurves = this.GetGridCurves(elementById as Grid);
					if (gridCurves != null && gridCurves.Count > 0)
					{
						list.AddRange(gridCurves);
					}
				}
			}
			if (list == null || list.Count <= 0)
			{
				return list;
			}
			if (ifNoReference)
			{
				list = (from n in list
				where null != n.Reference
				select n).ToList<Curve>();
			}
			return list;
		}

		private List<Curve> GetGridCurves(Grid grid)
		{
			List<Curve> list = new List<Curve>();
			Options options = this.m_app.Create.NewGeometryOptions();
			options.ComputeReferences = true;
			options.IncludeNonVisibleObjects = false;
			options.View = this.m_doc.ActiveView;
			GeometryElement geometryElement = grid.get_Geometry(options);
			if (geometryElement == null)
			{
				return null;
			}
			List<GeometryObject> geometryObjectArray = RevitVersionFuncs.GetGeometryObjectArray(geometryElement);
			foreach (GeometryObject geometryObject in geometryObjectArray)
			{
				if (geometryObject is Line)
				{
					Line item = geometryObject as Line;
					list.Add(item);
				}
				else if (geometryObject is Arc)
				{
					Arc item2 = geometryObject as Arc;
					list.Add(item2);
				}
			}
			return list;
		}

		private List<Element> GetParallelAxis(Element axisFirst, List<Element> lstDimAxis)
		{
			List<Element> list = new List<Element>();
			foreach (Element element in lstDimAxis)
			{
				if (this.IsParallel(axisFirst, element) && !list.Equals(element))
				{
					list.Add(element);
				}
			}
			return list;
		}

		private bool IsParallel(Element axis1, Element axis2)
		{
			List<Curve> axisCurves = this.GetAxisCurves(axis1, true);
			List<Curve> axisCurves2 = this.GetAxisCurves(axis2, true);
			for (int i = 0; i < axisCurves.Count; i++)
			{
				for (int j = 0; j < axisCurves2.Count; j++)
				{
					if (this.IsAxisCurveParallel(axisCurves[i], axisCurves2[j]) && axisCurves[i] is Line && axisCurves2[j] is Line)
					{
						return true;
					}
				}
			}
			return false;
		}

		private List<Element> LineCrossAxises(Line crossLine)
		{
			List<XYZ> list = new List<XYZ>();
			List<Element> list2 = new List<Element>();
			foreach (Element element in this.m_lstAllAxis)
			{
				if (this.IsAxisCanBeDim(element))
				{
					XYZ xyz = this.AxisIntersectLine(element, crossLine, null);
					if (xyz != null)
					{
						list.Add(xyz);
						list2.Add(element);
					}
				}
			}
			XYZ hyendPoint = crossLine.GetEndPoint(0);
			for (int i = 0; i < list2.Count; i++)
			{
				double num = hyendPoint.DistanceTo(list[i]);
				for (int j = i + 1; j < list2.Count; j++)
				{
					double num2 = hyendPoint.DistanceTo(list[j]);
					if (num > num2)
					{
						num = num2;
						XYZ value = list[i];
						list[i] = list[j];
						list[j] = value;
						Element value2 = list2[i];
						list2[i] = list2[j];
						list2[j] = value2;
					}
				}
			}
			return list2;
		}

		private XYZ AxisIntersectLine(Element axis, Line line, XYZ tempInputPoint = null)
		{
			List<Curve> axisCurves = this.GetAxisCurves(axis, false);
			if (axisCurves == null || axisCurves.Count < 1)
			{
				return null;
			}
			Curve curve = axisCurves[0];
			Curve curve2 = axisCurves[axisCurves.Count - 1];
			if (curve.GetType() != typeof(Line) || curve2.GetType() != typeof(Line))
			{
				return null;
			}
			XYZ xyz;
			if (tempInputPoint != null)
			{
				xyz = tempInputPoint;
			}
			else
			{
				xyz = line.GetEndPoint(0);
			}
			foreach (Curve curve3 in axisCurves)
			{
				Curve curve4 = DimPublicFunc.ChangeCurveElevation(curve3, xyz.Z);
				XYZ xyz2 = Geometry.IntersectWithTwoCurves(line, curve4, xyz, false, false, this.m_app);
				if (xyz2 != null)
				{
					return xyz2;
				}
			}
			return null;
		}

		private void GetDimRefInfo(List<Element> lstDimAxis, Line crossLine, bool nearCrossLine, ref List<ReferenceInfo> lstRefInfo)
		{
			foreach (Element axis in lstDimAxis)
			{
				ReferenceInfo referenceInfo = null;
				ReferenceInfo referenceInfo2 = null;
				this.GetAxisDimRefInfo(axis, ref referenceInfo, ref referenceInfo2);
				if (referenceInfo != null && referenceInfo2 != null)
				{
					XYZ xyz = this.AxisIntersectLine(axis, crossLine, null);
					if (nearCrossLine)
					{
						if (referenceInfo.ThePosition.DistanceTo(xyz) < referenceInfo2.ThePosition.DistanceTo(xyz))
						{
							lstRefInfo.Add(referenceInfo);
						}
						else
						{
							lstRefInfo.Add(referenceInfo2);
						}
					}
					else if (referenceInfo.ThePosition.DistanceTo(xyz) > referenceInfo2.ThePosition.DistanceTo(xyz))
					{
						lstRefInfo.Add(referenceInfo);
					}
					else
					{
						lstRefInfo.Add(referenceInfo2);
					}
				}
			}
		}

		private void GetAxisDimRefInfo(Element axis, ref ReferenceInfo refInfoStart, ref ReferenceInfo refInfoEnd)
		{
			List<Curve> axisCurves = this.GetAxisCurves(axis, true);
			if (axisCurves == null || axisCurves.Count < 1)
			{
				return;
			}
			for (int i = 0; i < axisCurves.Count; i++)
			{
				if (axisCurves[i].Reference == null)
				{
					axisCurves.RemoveAt(i);
					i--;
				}
			}
			if (axisCurves.Count == 1)
			{
				Line line = axisCurves[0] as Line;
				refInfoStart = new ReferenceInfo(line.Reference, line.GetEndPoint(0));
				refInfoEnd = new ReferenceInfo(line.Reference, line.GetEndPoint(1));
				return;
			}
			if (axisCurves.Count > 1)
			{
				Line line2 = axisCurves[0] as Line;
				XYZ hyendPoint = line2.GetEndPoint(0);
				XYZ hyendPoint2 = line2.GetEndPoint(1);
				XYZ hyendPoint3 = axisCurves[1].GetEndPoint(0);
				if (hyendPoint.DistanceTo(hyendPoint3) < hyendPoint2.DistanceTo(hyendPoint3))
				{
					refInfoStart = new ReferenceInfo(line2.Reference, hyendPoint2);
				}
				else
				{
					refInfoStart = new ReferenceInfo(line2.Reference, hyendPoint);
				}
				Line line3 = axisCurves[axisCurves.Count - 1] as Line;
				hyendPoint = line3.GetEndPoint(0);
				hyendPoint2 = line3.GetEndPoint(1);
				hyendPoint3 = axisCurves[axisCurves.Count - 2].GetEndPoint(0);
				if (hyendPoint.DistanceTo(hyendPoint3) < hyendPoint2.DistanceTo(hyendPoint3))
				{
					refInfoEnd = new ReferenceInfo(line3.Reference, hyendPoint2);
					return;
				}
				refInfoEnd = new ReferenceInfo(line3.Reference, hyendPoint);
			}
		}

		private XYZ GetAxisDimVector(Element axis, Line crossLine, bool bNearCross)
		{
			XYZ xyz = null;
			XYZ xyz2 = null;
			XYZ result = null;
			XYZ result2 = null;
			this.GetAxisDimPointAndVector(axis, ref xyz, ref xyz2, ref result, ref result2);
			XYZ xyz3 = this.AxisIntersectLine(axis, crossLine, null);
			if (bNearCross)
			{
				if (xyz.DistanceTo(xyz3) < xyz2.DistanceTo(xyz3))
				{
					return result;
				}
				return result2;
			}
			else
			{
				if (xyz.DistanceTo(xyz3) < xyz2.DistanceTo(xyz3))
				{
					return result2;
				}
				return result;
			}
		}

		private void GetAxisDimPointAndVector(Element axis, ref XYZ ptS, ref XYZ ptE, ref XYZ vtS, ref XYZ vtE)
		{
			List<Curve> list = this.GetAxisCurves(axis, true);
			list = (from n in list
			where null != n.Reference
			select n).ToList<Curve>();
			if (list.Count == 1)
			{
				Line curve = list[0] as Line;
				ptS = curve.GetEndPoint(0);
				ptE = curve.GetEndPoint(1);
				vtS = (ptS - ptE).Normalize();
				vtE = (ptE - ptS).Normalize();
				return;
			}
			if (list.Count > 1)
			{
				Line curve2 = list[0] as Line;
				XYZ hyendPoint = curve2.GetEndPoint(0);
				XYZ hyendPoint2 = curve2.GetEndPoint(1);
				XYZ hyendPoint3 = list[1].GetEndPoint(0);
				XYZ hyendPoint4 = list[1].GetEndPoint(1);
				if (hyendPoint.DistanceTo(hyendPoint3) < CmdAxisDim.precision || hyendPoint.DistanceTo(hyendPoint4) < CmdAxisDim.precision)
				{
					ptS = hyendPoint2;
					vtS = (hyendPoint2 - hyendPoint).Normalize();
				}
				else
				{
					ptS = hyendPoint;
					vtS = (hyendPoint - hyendPoint2).Normalize();
				}
				Line curve3 = list[list.Count - 1] as Line;
				hyendPoint = curve3.GetEndPoint(0);
				hyendPoint2 = curve3.GetEndPoint(1);
				hyendPoint3 = list[list.Count - 2].GetEndPoint(0);
				hyendPoint4 = list[list.Count - 2].GetEndPoint(1);
				if (hyendPoint.DistanceTo(hyendPoint3) < CmdAxisDim.precision || hyendPoint.DistanceTo(hyendPoint4) < CmdAxisDim.precision)
				{
					ptE = hyendPoint2;
					vtE = (hyendPoint2 - hyendPoint).Normalize();
					return;
				}
				ptE = hyendPoint;
				vtE = (hyendPoint - hyendPoint2).Normalize();
			}
		}

		private ReferenceInfo GetAxisWallBorderDimRef(XYZ ptAxisEnd, XYZ vtWallBorder)
		{
			Wall wall = null;
			double num = 0.0;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc, this.m_doc.ActiveView.Id);
			List<Wall> list = (from w in filteredElementCollector.OfClass(typeof(Wall))
			select w as Wall).ToList<Wall>();
			foreach (Wall wall2 in list)
			{
				if (!(wall2.LevelId != this.m_doc.ActiveView.GenLevel.Id))
				{
					LocationCurve locationCurve = wall2.Location as LocationCurve;
					if (!(locationCurve.Curve.GetType() != typeof(Line)))
					{
						Line line = locationCurve.Curve as Line;
						if (DimPublicFunc.IsVertical(vtWallBorder, line.Direction))
						{
							line = DimPublicFunc.ChangeLineElevation(line, ptAxisEnd.Z);
							XYZ xyz = Geometry.CalculateFootPoint(line, ptAxisEnd);
							double num2 = xyz.DistanceTo(ptAxisEnd);
							if (num2 < CmdAxisDim.precision)
							{
								if (wall == null)
								{
									wall = wall2;
								}
							}
							else if (num2 > num)
							{
								XYZ xyz2 = xyz - ptAxisEnd;
								if (Geometry.IsEqual(xyz2.Normalize(), vtWallBorder.Normalize()))
								{
									num = num2;
									wall = wall2;
								}
							}
						}
					}
				}
			}
			if (wall == null)
			{
				return null;
			}
			Line crossLine = YJKLineEx.YJKGetBound(ptAxisEnd, ptAxisEnd + vtWallBorder * 10.0);
			List<ReferenceInfo> list2 = new List<ReferenceInfo>();
            DimPublicFunc.GetWallThickRef(this.m_uiApp, wall, crossLine, (ViewDetailLevel)1, ref list2);
			if (list2.Count != 2)
			{
				return null;
			}
			ReferenceInfo referenceInfo = list2[0];
			ReferenceInfo referenceInfo2 = list2[1];
			XYZ xyz3 = referenceInfo.ThePosition - referenceInfo2.ThePosition;
			ReferenceInfo result;
			if (xyz3.AngleTo(vtWallBorder) < Math.PI*.5)
			{
				XYZ position = DimPublicFunc.SetPointZ(referenceInfo.ThePosition, ptAxisEnd.Z);
				result = new ReferenceInfo(referenceInfo.TheReference, position);
			}
			else
			{
				XYZ position2 = DimPublicFunc.SetPointZ(referenceInfo2.ThePosition, ptAxisEnd.Z);
				result = new ReferenceInfo(referenceInfo2.TheReference, position2);
			}
			return result;
		}

		private new static double precision = 0.00328;

		private List<Element> m_lstAllAxis;
	}
}
